#include<cstdlib>
#include<iostream>
//#include <initializer_list>
#include "swf.h"
#include "Tag.h"
#include "ShowFrame.h"
#include "SetBackgroundColor.h"
#include "PlaceObject2.h"
#include "DefineShape3.h"
#include "DefineText2.h"
#include "DefineFont2.h"
#include "CSMTextSettings.h"
#include "DefineShape.h"
#include "DefineBitsLossless.h"
#include "DefineText2.h"

using namespace std;
using namespace swfstream;
std::map<int, std::string> Tag::types; //={{1,""}};
Tag::Tag() {
	if (types.size() <= 0) {
		types[0] = "End";
		types[1] = "ShowFrame";
		types[9] = "SetBackgroundColor";
		types[26] = "PlaceObject2";
		types[32] = "DefineShape3";
		types[33] = "DefineText2";
		types[48] = "DefineFont2";
		types[69] = "FileAttributes";
		types[74] = "CSMTextSettings";
		types[77] = "Metadata";
		types[74] = "CSMTextSettings";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
		types[0] = "End";
	}
}
std::string Tag::getTypeName(int type) {
	std::map<int, string>::iterator it = types.find(type);
	if (it == types.end()) {
		return "";
	} else {
		return it->second;
	}
}
void Tag::print() {
	cerr << "tag::print" << endl;
	cerr << "header=" << header << endl;
	//printf("tag::type:%u,length:%u\n",(unsigned)header->type,(unsigned)header->length);
	//exit(2);

}
Tag* Tag::from_file(FILE*f) {
	//	puts("reading tag");
	Tag* r = new Tag;
//	printf("reading tag:");
	TagHeader *tag_header = new TagHeader;
	uint16 tmp;
	fread(&tmp, sizeof(tmp), 1, f);
	//	puts("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
	if (feof(f)) {
		return NULL;
	}
	tag_header->type = (tmp & 0xffc0) >> 6;
	tag_header->length = tmp & 0x3f;
	if (tag_header->length == 63) {
		uint32 tmp2;
		fread(&tmp2, sizeof(tmp2), 1, f);
		if (feof(f)) {
			return NULL;
		}
		tag_header->length = tmp2;
	}
//	printf("type=%u,length=%u\n",(uint)tag_header->type,(uint)tag_header->length);
	byte* buf = (byte*) malloc(tag_header->length);
	r->header = tag_header;
	if (tag_header->type == 0) { //done
		puts("end sag,file ends");
	} else if (tag_header->type == 1) { //done
		r = new ShowFrame;
		puts("ShowFrame,no more info");
	} else if (tag_header->type == 9) { //done
		puts("set background color");
		r = SetBackgroundColor::from_file(f);
		//	RGB *r=RGB::from_file(f);
		//	r->print();
	} else if (tag_header->type == 26) { //ok
		//fread(buf,tag_header.length,1,f);
		puts("PlaceObject2");
		r = PlaceObject2::from_file(f);
		r->header = tag_header;
		//r->print();
	} else if (tag_header->type == 32) { //ok
		puts("DefineShape3");
		//	fread(buf,tag_header->length,1,f);
		r = DefineShape3::from_file(f);
		//	r->header=tag_header;
		//	r->print();
		//	exit(5);
	} else if (tag_header->type == 33) { //done?
		puts("DefineText2");
		//		fread(buf,tag_header.length,1,f);
		//		FILE* ftag=fopen("tag.tmp","wb+");
		//		fwrite(buf,tag_header.length,1,ftag);
		//		fclose(ftag);
		r = DefineText2::from_file(f);
		//printf("@@@@@@@@@@@@@@@ r->TextRecords=%p\n",((define_text2*)r)->TextRecords);
		//	exit(0);
	} else if (tag_header->type == 48) { //done?
		//fread(buf,tag_header.length,1,f);
		puts("DefineFont2");
		//		fread(buf,tag_header.length,1,f);
		//	exit(0);
		//		FILE* ftag=fopen("tagfont.tmp","wb+");
		//		fwrite(buf,tag_header.length,1,ftag);
		//		fclose(ftag);
		r = DefineFont2::from_file(f, tag_header->length);
		//	exit(0);
	} else if (tag_header->type == 69) { //not care
		puts("file attributes");
		fread(buf, tag_header->length, 1, f);
	} else if (tag_header->type == 74) { //done,not care?
		puts("CSMTextSettings");
		r = CSMTextSettings::from_file(f);
		r->header = tag_header;
		//printf("%u,%u,%u,%u,%f,%f,%u\n",r.TextID,r.UseFlashType,r.GridFit,r.Reserved,r.Thickness,r.Sharpness,r.Reserved2);
		r->print();
	} else if (tag_header->type == TAG_TYPE_DEFINE_SHAPE) { //done
		//	fread(buf,tag_header->length,1,f);
		puts("define shape");
		r = DefineShape::from_file(f);
	} else if (tag_header->type == TAG_TYPE_DEFINE_BITS_LOSSLESS) {
		//fread(buf,tag_header->length,1,f);
		puts("define bits lossless");
		r = DefineBitsLossless::from_file(f, tag_header->length);
	} else {
		fprintf(stderr, "unknown tag type:%u\n", (uint) tag_header->type);
		exit(1);
	}
	free(buf);
	r->header = tag_header;
	tag_header->print();
	r->header->print();
	return r;
}
TiXmlElement* Tag::toTiXmlElement() {
	TiXmlElement *r = new TiXmlElement("Tag");
	r->LinkEndChild(header->toTiXmlElement());
	return r;
}
